package cn.jimmie.learn.viewArt.ball;

import android.content.Context;
import android.graphics.Canvas;
import android.os.CountDownTimer;
import android.view.WindowManager;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * function : 浮白视图, 负责逻辑
 *
 * <p> Create Time:  2019年01月02日 10:12 </p>
 * <p> @author Jimmie.Qian  </p>
 */
class AssistPopView extends AssistPopBaseView implements OnScreenChangedObserver {
    // =============== 倒计时 ===================
    // 浮白的显示时间
    private static final int SHOW_TIME = 5;
    private final WindowManager.LayoutParams mLayoutParams;
    private final WindowManager mWindowManager;
    // 消息池, 用于多条信息的管理
    private final List<Action> mPool = new ArrayList<>();
    private final MyCountDownTimer mTimer = new MyCountDownTimer();
    // 屏幕宽高, 屏幕变化时将更新
    private int W, H;
    // 是否添加到window
    private boolean isAttached;
    // 记录悬浮球的位置信息, 用于浮白的大小变化时,位置的微调
    private int lastX, lastY, size;

    public AssistPopView(Context context) {
        super(context, AssistPopBaseView.creator(context).config());

        mLayoutParams = LayoutParamUtils.createLayoutParams(context);
        // 设置不拦截任何触摸事件
        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        W = mWindowManager.getDefaultDisplay().getWidth();
        H = mWindowManager.getDefaultDisplay().getHeight();
    }

    /**
     * 添加到window,并且更新位置
     */
    public void attachToWindow(int x, int y, int size) {
        if (mMessage == null) return;
        lastX = x;
        lastY = y;
        this.size = size;
        int width = mConf.DIMEN.width;
        int type = orientation(x, y, size + 5);
        if (type == AssistBallView.RIGHT) {
            mPadding.xy(1f / 2, 1f / 2f);
            mLayoutParams.x = x - width;
            mLayoutParams.y = y + size / 2 - realHeight() / 2;
        } else if (type == AssistBallView.LEFT) {
            mPadding.xy(1f / 2, 1f / 2);
            mLayoutParams.x = x + size;
            mLayoutParams.y = y + size / 2 - realHeight() / 2;
        } else if (type == AssistBallView.TOP) {
            int a = x + size / 2;
            int b = y + size;
            if (a < width / 2) {
                mPadding.xy(1f * a / width, 0);
                mLayoutParams.x = 0;
                mLayoutParams.y = b;
            } else if (a > W - width / 2) {
                float radio = 1f - 1f * (W - a) / width;
                mPadding.xy(radio, radio);
                mLayoutParams.x = W - width;
                mLayoutParams.y = b;
            } else {
                mPadding.xy(1f / 2, 1f / 2);
                mLayoutParams.x = a - width / 2;
                mLayoutParams.y = b;
            }
        } else {
            int a = x + size / 2;
            if (a < width / 2) {
                mPadding.xy(1f * a / width, 0);
                mLayoutParams.x = 0;
                mLayoutParams.y = y - realHeight();
            } else if (a > W - width / 2) {
                float radio = 1f - 1f * (W - a) / width;
                mPadding.xy(radio, radio);
                mLayoutParams.x = W - width;
                mLayoutParams.y = y - realHeight();
            } else {
                mPadding.xy(1f / 2, 1f / 2);
                mLayoutParams.x = a - width / 2;
                mLayoutParams.y = y - realHeight();
            }
        }
        mPadding.set(type, mConf.DIMEN.arrowWidth);
        requestLayout();
        if (!isAttached) {
            isAttached = true;
            mWindowManager.addView(this, mLayoutParams);
        } else {
            mWindowManager.updateViewLayout(this, mLayoutParams);
        }
    }

    /**
     * 从window中移除
     */
    public void detachFromWindow() {
        mMessage = null;
        mTimer.end();
        mPool.clear();
        if (isAttached) {
            isAttached = false;
            mWindowManager.removeViewImmediate(this);
        }
    }

    /**
     * 添加消息到浮白中
     */
    public void addMessage(AssistBall.Message message, AssistBall.OnAssistPopEventListener listener) {
        if (message == null) return;

        Action action = new Action(message, listener);

        setTitleStyle();
        measureTitle(message, mConf.DIMEN);
        setContentStyle();
        measureLines(message, mPaint, mConf.DIMEN);

        if (mTimer.isStop()) {
            setListener(listener);
            mMessage = message;
            mTimer.begin();
        } else {
            mPool.add(action);
        }
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }

    @Override
    public void onLayoutChanged(int width, int height) {
        W = width;
        H = height;
    }

    @Override
    boolean hasNext() {
        return !mMessage.isIndiePop && getNextCount() > 0;
    }

    @Override
    int getNextCount() {
        int count = 0;
        for (Action action : mPool) {
            if (!action.message.isIndiePop) count++;
        }
        return count;
    }

    @Override
    void onNextEvent(boolean byUser) {
        super.onNextEvent(byUser);
        if (!mPool.isEmpty()) {
            Action action = mPool.get(0);
            mPool.remove(0);
            mMessage = action.message;
            setListener(action.listener);
            attachToWindow(lastX, lastY, size);
            mTimer.end();
            mTimer.begin();
        } else {
            detachFromWindow();
        }
    }

    // =============== inner class ===============

    @Override
    void onCloseEvent(boolean byUser) {
        super.onCloseEvent(byUser);
        // 独立类型
        if (mMessage.isIndiePop) {
            onNextEvent(false);
        }
        // 组合类型
        else {
            Iterator<Action> iterator = mPool.iterator();
            while (iterator.hasNext()) {
                Action action = iterator.next();
                if (!action.message.isIndiePop) {
                    iterator.remove();
                }
            }
            onNextEvent(false);
        }
    }

    private int orientation(int x, int y, int size) {
        int o = AssistBallView.LEFT;
        if (y <= size) o = AssistBallView.TOP;
        else if (y >= H - size) o = AssistBallView.BOTTOM;
        else if (x >= W - size) o = AssistBallView.RIGHT;
        return o;
    }

    final class Action {
        AssistBall.Message message;
        AssistBall.OnAssistPopEventListener listener;

        Action(AssistBall.Message message, AssistBall.OnAssistPopEventListener listener) {
            this.message = message;
            this.listener = listener;
        }
    }

    /**
     * 内部的计时器类
     */
    private class MyCountDownTimer extends CountDownTimer {
        private boolean isStop = true;

        MyCountDownTimer() {
            super(SHOW_TIME * 1000, 1000);
        }

        @Override
        public void onTick(long millisUntilFinished) {
        }

        @Override
        public void onFinish() {
            isStop = true;
            onNextEvent(false);
        }

        void end() {
            isStop = true;
            cancel();
        }

        void begin() {
            isStop = false;
            start();
        }

        boolean isStop() {
            return isStop;
        }
    }
}
